package com.sg.common.empty.core;

import java.io.FileReader;
import java.io.IOException;
import java.util.List;

import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.sg.common.empty.service.CfgService;
import com.sg.common.login.entity.Member;
import com.sg.common.login.entity.Org;
import com.sg.common.login.entity.Role;
import com.sg.common.login.service.OrgMemberService;
import com.sg.common.utils.CollUtil;
import com.sg.common.utils.Constant;
import com.sg.common.utils.StrUtil;
import com.typesafe.config.Config;

/**
 * 默认permission的处理方法，其他个性化处理通过继承此方法进行处理
 * 
 * @author wangze
 * 
 */
public class DealPermission {

	private Logger logger = LoggerFactory.getLogger(getClass());

	HttpServletRequest request;

	CfgService service;

	OrgMemberService omService;

	// 用于判断该功能需要的权限类型
	// 0 标准功能，需分配权限
	// 1 无需权限
	// 2 需登录权限
	private int type = 1;

	// 关联的角色
	List<String> roles;
	// 关联的组织
	List<String> orgs;
	// 关联的人员
	List<String> persons;

	// 关联的人员
	String js;

	// 处理类的名称
	String dealClass;

	private String jsfile;

	public boolean getCanIn() throws ServletException, IOException {
		boolean canin = false;
		if (type != 0) {
			return true;
		}
		if(CollUtil.isEmpty(persons)
				&&CollUtil.isEmpty(roles)
				&&CollUtil.isEmpty(orgs)
				&&StringUtils.isEmpty(js)
				&&StringUtils.isEmpty(jsfile)){
			return true;
		}
		if ((!canin) && CollUtil.isNotEmpty(persons)) {
			Member curmember = Constant.getSessionMember(request);
			canin = persons.contains(curmember.getCode());
		}
		if ((!canin) && CollUtil.isNotEmpty(roles)) {
//			List<Role> myRoles = (List<Role>) request.getSession()
//					.getAttribute(Constant.SESSION_MYROLES);
//			if (CollUtil.isNotEmpty(myRoles)) {
//				for (Role myRole : myRoles) {
//					if (roles.contains(myRole.getRole())) {
//						canin = true;
//						break;
//					}
//				}
//			}
			List<String> myRoles = (List<String>) request.getSession()
					.getAttribute(Constant.SESSION_MYROLES_CODE);
			if (CollUtil.isNotEmpty(myRoles)) {
				for (String myRole : myRoles) {
					if (roles.contains(myRole)) {
						canin = true;
						break;
					}
				}
			}
		}
		if ((!canin) && CollUtil.isNotEmpty(orgs)) {
			List<Org> myOrgs = (List<Org>) request.getSession().getAttribute(
					Constant.SESSION_MYORGS);
			if (CollUtil.isNotEmpty(myOrgs)) {
				for (Org myOrg : myOrgs) {
					if (orgs.contains(myOrg.getCode())) {
						canin = true;
						break;
					}
				}
			}
		}

		if ((!canin) && StringUtils.isNotEmpty(js)) {
			ScriptEngineManager factory = new ScriptEngineManager();// step
			ScriptEngine engine = factory.getEngineByName("JavaScript");// Step
			engine.put("request", request);
			try {
				engine.eval(js);
				canin = (Boolean) engine.get("cando");
			} catch (ScriptException e) {
				logger.error(e.getMessage());
			}
		}

		if ((!canin) && StringUtils.isNotEmpty(jsfile)) {
			FileReader fr = new FileReader(jsfile);
			ScriptEngineManager factory = new ScriptEngineManager();// step
			ScriptEngine engine = factory.getEngineByName("JavaScript");// Step
			engine.put("request", request);
			try {
				engine.eval(fr);
				canin = (Boolean) engine.get("cando");
			} catch (ScriptException e) {
				logger.error(e.getMessage());
			}
		}
		return canin;
	}

	public static DealPermission init(HttpServletRequest request,
			CfgService service, OrgMemberService omService, String route,
			int type) {
		DealPermission one = new DealPermission();
		one.request = request;
		one.service = service;
		one.omService = omService;
		one.roles = Constant.getStringList(StrUtil.dot(route, "roles"));
		one.persons = Constant.getStringList(StrUtil.dot(route, "persons"));
		one.orgs = Constant.getStringList(StrUtil.dot(route, "orgs"));
		one.type = type;
		one.js = Constant.get(StrUtil.dot(route, "js"));
		return one;

	}

	/**
	 * 初始化不是route下的权限参数，即非页面权限，而是页面中显示那块数据的权限
	 * 
	 * @param request
	 * @param service
	 * @param omService
	 * @param config
	 * @return
	 */
	public static DealPermission init(HttpServletRequest request,
			CfgService service, OrgMemberService omService, Config config,
			String key) {
		DealPermission one = new DealPermission();
		one.request = request;
		one.service = service;
		one.omService = omService;
		one.roles = Constant.getStringList(config, StrUtil.dot(key, "roles"));
		one.persons = Constant.getStringList(config,
				StrUtil.dot(key, "persons"));
		one.orgs = Constant.getStringList(config, StrUtil.dot(key, "orgs"));
		one.type = 0;// 数据块权限默认0模式
		// one.type = Constant.getInt(StrUtil.dot(route, "type"));
		// one.js = Constant.get(StrUtil.dot(route, "js"));
		return one;
	}

	/**
	 * 页面权限初始化
	 * 
	 * @param request
	 * @param service
	 * @param omService
	 * @return
	 */
	public static DealPermission init(HttpServletRequest request,
			CfgService service, OrgMemberService omService) {
		DealPermission one = new DealPermission();
		String route = (String) request.getAttribute("conf.route");
		one.request = request;
		one.service = service;
		one.omService = omService;
		one.roles = Constant.getStringList(StrUtil.dot(route, "roles"));
		one.persons = Constant.getStringList(StrUtil.dot(route, "persons"));
		one.orgs = Constant.getStringList(StrUtil.dot(route, "orgs"));
		Integer typeConf = Constant.getInt(StrUtil.dot(route, "type"));
		if (typeConf != null) {
			one.type = typeConf;
		}
		one.js = Constant.get(StrUtil.dot(route, "js"));
		return one;
	}

	/**
	 * 引用：intercept 页面权限
	 * 有dealclass参数的，先确定使用哪个类 再初始化
	 * 
	 * @param request
	 * @param service
	 * @param omService
	 * @return
	 * @throws ClassNotFoundException
	 * @throws InstantiationException
	 * @throws IllegalAccessException
	 */
	public static DealPermission permissionClazz(HttpServletRequest request,
			CfgService service, OrgMemberService omService)
			throws ClassNotFoundException, InstantiationException,
			IllegalAccessException {
		String route = (String) request.getAttribute("conf.route");
		String perDealClass = Constant.get(StrUtil.dot(route, "dealClass"));
		DealPermission dealPermission = null;
		if (StringUtils.isEmpty(perDealClass)) {
			dealPermission = init(request, service, omService);
		} else {
			Class<?> clazz;
			clazz = Class.forName(perDealClass);
			dealPermission = (DealPermission) clazz.newInstance();
			dealPermission.service = service;
			dealPermission.request = request;
			dealPermission.omService = omService;
		}
		return dealPermission;
	}

	public static DealPermission permissionClazz(String route,
			HttpServletRequest request, CfgService service,
			OrgMemberService omService) throws ClassNotFoundException,
			InstantiationException, IllegalAccessException {
		String perDealClass = Constant.get(StrUtil.dot(route, "dealClass"));
		DealPermission dealPermission = null;
		if (StringUtils.isEmpty(perDealClass)) {
			dealPermission = init(request, service, omService);
		} else {
			Class<?> clazz;
			clazz = Class.forName(perDealClass);
			dealPermission = (DealPermission) clazz.newInstance();
			dealPermission.service = service;
			dealPermission.request = request;
			dealPermission.omService = omService;
		}
		return dealPermission;
	}
}
